package jobs

import (
	"context"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os/exec"
	"strconv"
	"strings"
	"sync"
	"time"

	"game_process_monitor/util"

	"github.com/go-kit/log/level"
	"github.com/patrickmn/go-cache"
)

var wg sync.WaitGroup
var wlock sync.RWMutex
var GoCache *cache.Cache
var AltStr []string

// psCronFunc  crontab func of catch ps info
func PsCronFunc() {
	defer func() {
		AltStr = []string{}
	}()
	procConfigFile, err := util.AbsPath(*util.ProConfig)
	if err != nil {
		level.Error(util.Logger).Log("err", err)
		panic(err)
	}
	alertLogPath, err := util.AbsPath("alert.log")
	if err != nil {
		level.Error(util.Logger).Log("err", err)
		panic(err)
	}
	// alert
	ctx, cancel := context.WithTimeout(context.Background(), time.Duration(5)*time.Second)
	defer cancel()
	procMap := make(map[string]int)
	data, err := ioutil.ReadFile(procConfigFile)
	if err != nil {
		level.Error(util.Logger).Log("err", err)
		return
	}
	//fmt.Println(string(data))
	err = json.Unmarshal(data, &procMap)
	if err != nil {
		level.Error(util.Logger).Log("err", err)
		return
	}

	for k, _ := range procMap {
		wg.Add(1)
		go procCheck(ctx, k, procMap)
	}
	wg.Wait()
	go util.WriteAndAlert(alertLogPath, strings.Join(AltStr, " "))
}

//获取服务器进程信息；收集宕机信息
func procCheck(ctx context.Context, pro string, promap map[string]int) {
	defer wg.Done()
	level.Info(util.Logger).Log("check process", pro)
	psStr := fmt.Sprintf("ps aux|egrep -v \"grep|SCREEN\" | grep \"%s\"|wc -l", pro)
	cmd := exec.CommandContext(ctx, "sh", "-c", psStr)
	out, err := cmd.CombinedOutput()
	if err != nil {
		level.Error(util.Logger).Log("err", err)
		return
	}
	num, err := strconv.Atoi(strings.TrimSuffix(string(out), "\n"))
	if err != nil {
		level.Error(util.Logger).Log("err", err)
		return
	}
	GoCache.Set(pro, []int{num, promap[pro] - num}, 60*time.Second)
	GoCache.DeleteExpired()
	// 和配置文件对比 配置文件-实际
	proRes := promap[pro] - num
	if proRes == 0 {
	} else {
		defer wlock.Unlock()
		wlock.Lock()
		// 异常数量是可能由于在进行热加载导致多出来一个进程
		if proRes > 0 {
			AltStr = append(AltStr, "进程"+pro+"宕机数量"+strconv.Itoa(proRes))
		} else {
			AltStr = append(AltStr, "进程"+pro+"异常数量"+strconv.Itoa(proRes))
		}

		// n := strconv.Itoa(proRes)

	}
}
